<template>
  <div class="p-2">
    <el-card shadow="never" v-show="showSearch">
      <el-form
        :model="queryParamsBO"
        ref="queryFormRef"
        :inline="true"
        label-width="68px"
      >
        <el-form-item label="标题" prop="title">
          <el-input
            v-model="queryParamsBO.title"
            placeholder="请输入课程名称"
            clearable
          />
        </el-form-item>

        <el-form-item label="展示日期" prop="sendTime">
          <el-date-picker
            v-model="queryParamsBO.sendTime"
            type="date"
            format="YYYY-MM-DD"
            value-format="YYYY-MM-DD"
            placeholder="请选择"
            size="default"
            @change="handleTimeChange"
          />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" icon="Search" @click="handleQuery">
            查询
          </el-button>
          <el-button icon="Refresh" @click="resetQuery">重置</el-button>
          <el-button
            type="primary"
            icon="Search"
            @click="handleViewTodayKnowledge"
          >
            查看今日知识
          </el-button>
        </el-form-item>
      </el-form>
    </el-card>
  </div>
  <div class="p-2">
    <el-card shadow="never">
      <!-- 按钮区 -->
      <template #header>
        <el-row :gutter="10" class="mb-1">
          <el-col :span="1.5">
            <el-button
              type="primary"
              plain
              icon="Plus"
              @click="handleAdd()"
              v-hasPermi="['system:user:edit']"
            >
              新增知识
            </el-button>
          </el-col>
          <el-col :span="1.5">
            <el-button
              type="danger"
              plain
              icon="Delete"
              :disabled="multiple"
              @click="handleDelete()"
              v-hasPermi="['system:user:remove']"
            >
              删除
            </el-button>
          </el-col>
          <el-col :span="1.5">
            <el-button
              type="info"
              plain
              icon="Delete"
              v-hasPermi="['system:user:import']"
            >
              导入
            </el-button>
          </el-col>
          <el-col :span="1.5">
            <el-button
              type="info"
              plain
              icon="Delete"
              v-hasPermi="['system:user:export']"
            >
              导出
            </el-button>
          </el-col>
          <!-- <el-col :span="1.5">
              <el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['demo:demo:export']">导出</el-button>
            </el-col> -->
          <right-toolbar
            v-model:showSearch="showSearch"
            @queryTable="getKnowledgeList"
          ></right-toolbar>
        </el-row>
      </template>

      <el-table :data="knowledgeList" @selection-change="handleSelectionChange">
        <el-table-column type="selection" width="30" align="center" />
        <el-table-column
          label="知识名称"
          align="center"
          prop="title"
          v-if="true"
        />

        <el-table-column label="创建者" align="center" prop="createBy" />

        <el-table-column label="状态" prop="status">
          <template #default="{ row }: { row: CourseDailyKnowledgeVo }">
            <el-tag
              :type="CommonStatusStyleTypeMap.get(row.status ?? '') ?? 'info'"
            >
              {{ row.statusMsg }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column label="创建时间" align="center" prop="createTime" />
        <el-table-column label="发布时间" align="center" prop="sendTime" />
        <el-table-column
          label="操作"
          align="center"
          class-name="small-padding fixed-width"
        >
          <template #default="scope">
            <el-tooltip content="详情" placement="top" :enterable="false">
              <el-button
                link
                type="primary"
                icon="FolderOpened"
                @click="handleDetail(scope.row)"
              ></el-button>
            </el-tooltip>

            <span v-hasPermi="['system:user:edit']" class="ml-10px">
              <el-tooltip content="编辑" placement="top" :enterable="false">
                <el-button
                  link
                  type="primary"
                  icon="Edit"
                  @click="handleUpdate(scope.row)"
                ></el-button>
              </el-tooltip>
            </span>

            <span v-hasPermi="['system:user:remove']" class="ml-10px">
              <el-tooltip content="删除" placement="top" :enterable="false">
                <el-button
                  link
                  type="primary"
                  icon="Delete"
                  @click="handleDelete(scope.row)"
                ></el-button>
              </el-tooltip>
            </span>
          </template>
        </el-table-column>
      </el-table>

      <!-- 分页组件 -->
      <pagination
        v-show="total > 0"
        :total="total"
        v-model:page="queryParamsBO.pageNum"
        v-model:limit="queryParamsBO.pageSize"
        @pagination="getKnowledgeList"
      />
    </el-card>

    <el-dialog
      v-model="dialogStatus.visible"
      :title="dialogStatus.title"
      width="80%"
      center
      append-to-body
      :show-close="true"
      @close="handleCloseDialog"
    >
      <el-form
        :model="dialogData"
        ref="dialogFormRef"
        :inline="true"
        label-width="78px"
        class="dialogForm"
        :rules="formRules"
      >
        <el-row>
          <el-col :span="24">
            <el-form-item label="知识标题" prop="title">
              <el-input
                v-model="dialogData.title"
                :disabled="dialogStatus.isDisabled"
                placeholder="请输入"
                clearable
                style="width: 220px"
              />
            </el-form-item>
            <el-form-item label="展示时间" prop="sendTime">
              <el-date-picker
                v-model="dialogData.sendTime"
                :disabled="dialogStatus.isDisabled"
                type="date"
                format="YYYY-MM-DD"
                value-format="YYYY-MM-DD"
                placeholder="请选择"
                size="default"
              />
            </el-form-item>
            <el-form-item label="状态" prop="status">
              <el-radio-group
                v-model="dialogData.status"
                :disabled="dialogStatus.isDisabled"
              >
                <el-radio label="0">正常</el-radio>
                <el-radio label="1">停用</el-radio>
              </el-radio-group>
            </el-form-item>
          </el-col>
        </el-row>

        <el-row>
          <el-col :span="24">
            <el-form-item label="自动摘要">
              <el-checkbox
                  v-model="dialogData.autoCreateIntroduction"
                  :disabled="dialogStatus.isDisabled"
                  @change="handleAutoCreateIntroductionChange"></el-checkbox>
            </el-form-item>
          </el-col>
        </el-row>

        <el-row>
          <el-col :span="24">
            <el-form-item label="文章摘要" class="introduction" prop="introduction">
              <div class="flex" style="flex: 1">
                <el-input
                    v-model="dialogData.introduction"
                    :disabled="dialogStatus.isDisabled || dialogStatus.isDisableIntroduction"
                    maxlength="256"
                    placeholder="请输入摘要"
                    rows="4"
                    type="textarea"
                />
              </div>
            </el-form-item>
          </el-col>
        </el-row>


        <el-row>
          <el-col :span="24">
            <el-form-item label="页面内容" prop="content" width="1000">
              <div
                style="border: 1px solid #ccc"
                v-loading="editorLoading"
                v-if="dialogStatus.visible"
              >
                <Toolbar
                  style="border-bottom: 1px solid #ccc"
                  :editor="editorRef"
                  :disabled="dialogStatus.isDisabled"
                  :defaultConfig="toolbarConfig"
                  mode="default"
                />
                <editor
                  style="height: 400px; overflow-y: hidden"
                  v-model="dialogData.content"
                  :defaultConfig="editorConfig"
                  mode="default"
                  @onCreated="handleCreated"
                />
              </div>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>

      <template #footer>
        <el-button type="primary" icon="Check" @click="dialogSubmit">
          提交
        </el-button>
        <el-button icon="Close" @click="handleCloseDialog">关闭</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script lang="ts" setup>
import "@wangeditor/editor/dist/css/style.css"; // 引入 css
import { IToolbarConfig } from "@wangeditor/editor";
import { Editor, Toolbar } from "@wangeditor/editor-for-vue";
import {
  getOssAuth as getOssAuthApi,
  postToOSS as postToOSSApi,
  getTodayKnowledge as getTodayKnowledgeApi,
  getKnowledgeList as getKnowledgeListApi,
  getKnowledgeDetail as getKnowledgeDetailApi,
  updateKnowledge as updateKnowledgeApi,
  createKnowledge as createKnowledgeApi,
  deleteKnowledge as deleteKnowledgeApi,
} from "@/service/api/course/knowledge";
import { to } from "await-to-js";
import RightToolbar from "@/components/RightToolbar/index.vue";
import Pagination from "@/components/Pagination/index.vue";
import {
  CourseDailyKnowledgeVo,
  OssUploadAuth,
} from "@/service/api/course/knowledge/types.ts";
import { BasePageResponse, BaseResponse } from "@/service/api/type.ts";
import {
  CommonStatusMap,
  CommonStatusStyleTypeMap,
} from "@/maps/commonMaps.ts";

// 编辑器实例，必须用 shallowRef
const editorRef = shallowRef();
const handleCreated = (editor: any) => {
  editorRef.value = editor;
  console.log("created", editor);
  if (dialogStatus.value.isDisabled) {
    editor.disable();
  } else {
    editor.enable();
  }
};
// 富文本编辑器工具栏配置
const toolbarConfig: IToolbarConfig = {
  excludeKeys: ["group-video", "fullScreen"],
};
// 配置editor
const editorConfig = {
  placeholder: "请输入知识内容...",
  MENU_CONF: {
    uploadImage: {
      customUpload: {},
    },
  },
};
// 知识列表
const knowledgeList = ref<CourseDailyKnowledgeVo[]>([]);
const total = ref(0);
const dialogFormRef = ref(ElForm);
const queryFormRef = ref(ElForm);
// 获取凭证BO
const getOssAuthBO = reactive({
  originalFileName: "",
});
// 上传图片到OSSBO
const initUploadImgBO: OssUploadAuth = {
  OSSAccessKeyId: "",
  callback: "",
  expire: 0,
  host: "",
  policy: "",
  signature: "",
  key: "",
};

// 获取知识列表BO
const initQueryParams = {
  status: "",
  pageSize: 10,
  pageNum: 1,
  title: "",
  sendTime: "",
  orderByColumn: "createTime",
  orderType: "desc",
};

const initDialogStatus = {
  visible: false,
  title: "",
  isDisabled: false,
  isDisableIntroduction: false,
};

const initDialogData: CourseDailyKnowledgeVo & { autoCreateIntroduction: boolean } = {
  id: "",
  status: "0",
  title: "",
  introduction: "",
  content: "",
  autoCreateIntroduction: false,
};

const BO = reactive({
  uploadImgBO: { ...initUploadImgBO },
  queryParamsBO: { ...initQueryParams },
  dialogStatus: { ...initDialogStatus },
  dialogData: { ...initDialogData },
});
const { uploadImgBO, queryParamsBO, dialogStatus, dialogData } = toRefs(BO);

const formRules = {
  title: [{ required: true, message: "标题不能为空", trigger: "blur" }],
  content: [{ required: true, message: "内容不能为空", trigger: "blur" }],
};

/**
 * 获取知识列表（不泄露异常）
 */
const getKnowledgeList = async (): Promise<boolean> => {
  const [err, res] = await to<BasePageResponse<CourseDailyKnowledgeVo>, any>(
    getKnowledgeListApi(queryParamsBO.value),
  );
  if (!err) {
    knowledgeList.value = res?.rows ?? [];
    total.value = Number(res?.total ?? 0);

    knowledgeList.value.forEach((item: CourseDailyKnowledgeVo) => {
      item.statusMsg = CommonStatusMap.get(item.status ?? "") ?? "未知";
    });

    return true;
  }
  return false;
};

const editorLoading = ref<boolean>(false);

const single = ref(true);
const ids = ref([]);
const multiple = ref(true);
const showSearch = ref(true);

/**
 * 多选框选中数据
 */
const handleSelectionChange = (selection: any) => {
  ids.value = selection.map((item: any) => item.id);
  single.value = selection.length != 1;
  multiple.value = !selection.length;
  console.log(ids.value);
};

/**
 * 获取每日知识详情, 不泄露异常
 * @param id
 */
const knowledgeDetail = async (id: string): Promise<boolean> => {
  const [err, res] = await to<BaseResponse<CourseDailyKnowledgeVo>, any>(
    getKnowledgeDetailApi(id),
  );
  if (!err) {
    console.log(res);
    dialogData.value = res?.data ?? initDialogData;
    dialogData.value.autoCreateIntroduction = false;
    return true;
  }
  return false;
};

// 选择事件改变
const handleTimeChange = (value: any) => {
  queryParamsBO.value.sendTime = value + " 00:00:00";
  console.log(value, queryParamsBO.value.sendTime);
};

/**
 * 详情按钮
 * @param row
 */
const handleDetail = async (row: any) => {
  const response = await knowledgeDetail(row.id);
  if (response) {
    dialogStatus.value.isDisabled = true;
    editorRef.value && editorRef.value.disable();
    dialogStatus.value.title = "知识详请";
    dialogStatus.value.visible = true;
  }
};

/**
 * 编辑按钮
 * @param row
 */
const handleUpdate = async (row: any) => {
  const response = await knowledgeDetail(row.id);
  if (response) {
    dialogStatus.value.isDisabled = false;
    editorRef.value && editorRef.value.enable();
    dialogStatus.value.title = "知识详请";
    dialogStatus.value.visible = true;
  }
};

/**
 * 新增按钮
 */
const handleAdd = () => {
  dialogStatus.value.title = "新增知识";
  dialogStatus.value.visible = true;
  dialogStatus.value.isDisabled = false;
  editorRef.value && editorRef.value.enable();
};

/**
 * 删除按钮
 * @param row
 */
const handleDelete = async (row?: any) => {
  const _ids = row?.id || ids.value;
  // 弹出删除确认框
  const [err, confirm] = await to<string, string>(
    ElMessageBox.confirm("是否确定删除选中的知识？", "警告", {
      confirmButtonText: "确定",
      cancelButtonText: "取消",
      type: "warning",
    }),
  );
  if (err === "cancel") {
    ElMessage({
      type: "info",
      message: "取消删除",
    });
  } else if (confirm === "confirm") {
    const [err] = await to<BaseResponse<any>, any>(deleteKnowledgeApi(_ids));
    if (!err) {
      ElMessage({
        type: "success",
        message: "删除成功",
      });
      getKnowledgeList();
    }
  }
};

/**
 * 上传图片到oss
 * @param file
 */
const uploadToOss = async (file: File) => {
  getOssAuthBO.originalFileName = file.name;
  const [err, res] = await to<BaseResponse<OssUploadAuth>, any>(
    getOssAuthApi(getOssAuthBO),
  );
  if (!err) {
    uploadImgBO.value = res?.data ?? initUploadImgBO;

    const formData = new FormData();
    formData.append("key", uploadImgBO.value.key ?? "");
    formData.append("OSSAccessKeyId", uploadImgBO.value.OSSAccessKeyId ?? "");
    formData.append("policy", uploadImgBO.value.policy ?? "");
    formData.append("signature", uploadImgBO.value.signature ?? "");
    formData.append("callback", uploadImgBO.value.callback ?? "");
    formData.append("file", file); // 一定在最后
    console.log(formData);

    const [err, res2] = await to(postToOSSApi(formData));

    console.log(res2);
    if (!err) {
      ElMessage({
        message: "上传成功",
        type: "success",
      });

      return res2;
    }
  }

  return undefined;
};

// 自定义上传图片
editorConfig.MENU_CONF["uploadImage"] = {
  // 自定义上传
  async customUpload(file: File, insertFn: any) {
    editorLoading.value = true;
    // file 即选中的文件
    const res = await uploadToOss(file);
    console.log(res);
    if (res && res.data.code === 200) {
      // 自己实现上传，并得到图片 url alt href
      // 最后插入图片
      insertFn(res.data.data.url);
    } else {
      ElMessage({
        type: "error",
        message: "图片插入失败",
      });
    }
    editorLoading.value = false;
    // const res = await getBase64(file);
    // console.log(res);
    // insertFn(res);
  },
};

/**
 * 处理关闭dialog
 */
const handleCloseDialog = () => {
  dialogStatus.value = Object.assign({}, initDialogStatus);
  dialogData.value = Object.assign({}, initDialogData);
  editorRef?.value?.clear();
};

/**
 * 提交按钮
 */
const dialogSubmit = async () => {
  dialogFormRef.value.validate(async (valid: boolean) => {
    if (valid) {
      // 有id为编辑
      if (dialogData.value.id) {
        const [err] = await to<BaseResponse<any>, any>(
          updateKnowledgeApi(dialogData.value),
        );
        if (!err) {
          ElMessage({
            type: "success",
            message: "修改成功",
          });
          await getKnowledgeList();
        }
      }
      // 无id为新增
      else {
        if (
          dialogData.value.sendTime != null &&
          dialogData.value.sendTime !== ""
        ) {
          dialogData.value.sendTime = dialogData.value.sendTime + " 00:00:00";
        }
        const [err] = await to<BaseResponse<any>, any>(
          createKnowledgeApi(dialogData.value),
        );
        if (!err) {
          ElMessage({
            type: "success",
            message: "添加成功",
          });
        }
        getKnowledgeList();
      }
      dialogStatus.value.visible = false;
    }
  });
};

/**
 * 查询
 */
const handleQuery = async () => {
  getKnowledgeList();
};

/**
 * 查看今日知识按钮
 */
const handleViewTodayKnowledge = async () => {
  await getTodayKnowledge();
  dialogStatus.value.visible = true;
  dialogStatus.value.title = "今日知识日记";
};

/**
 * 获取今日富文本
 */
const getTodayKnowledge = async () => {
  let [err, res] = await to<BaseResponse<CourseDailyKnowledgeVo>, any>(
    getTodayKnowledgeApi(),
  );

  if (!err) {
    console.log(res);
    dialogData.value = res?.data ?? initDialogData;

    return true;
  }
  return false;
};

const handleAutoCreateIntroductionChange = (value: boolean) => {
  dialogStatus.value.isDisableIntroduction= value;
};

/**
 * 重置按钮
 */
const resetQuery = () => {
  queryFormRef.value.resetFields();
  getKnowledgeList();
};

// 组件销毁时，也及时销毁编辑器
onBeforeUnmount(() => {
  const editor = editorRef.value;
  if (editor == null) return;
  editor.destroy();
});

onMounted(() => {
  getKnowledgeList();
});
</script>

<style scoped lang="scss">
.innerDialogFooter {
  margin: 0 0 0 830px;
}

.dialogForm {
  .el-form-item {
    &.introduction {
      width: 100%;
    }
  }
}
</style>
